/// @tags: Lagrange
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>
#define rint register int

using std::cin;
using std::cout;

namespace BlueQuantum {

typedef long long LL;

constexpr int MAXN = 43, P = 1e9 + 7;

int n, m, e[MAXN][MAXN][4];
LL det[MAXN][MAXN], deg[MAXN][MAXN];

inline LL qpow(LL base, int exp = P - 2) {
  LL res = 1;
  for (; exp; exp >>= 1, base = base * base % P)
    if (exp & 1) res = res * base % P;
  return res;
}

inline void matrixTree(int x, int y) {
  LL sum = 1;
  memset(deg, 0, sizeof(deg));
  for (rint i = 1; i <= n; ++i)
    for (rint j = 1; j <= n; ++j) {
      if (i == j) continue;
      deg[i][j] -= e[i][j][1] + e[i][j][2] * x + e[i][j][3] * y;
      deg[i][i] += e[i][j][1] + e[i][j][2] * x + e[i][j][3] * y;
    }
  for (rint i = 1; i <= n; ++i)
    for (rint j = 1; j <= n; ++j) deg[i][j] = (deg[i][j] + P) % P;
  for (rint i = 1; i < n; ++i) {
    rint tar = i;
    for (rint j = i; j < n; ++j)
      if (deg[j][i]) {
        tar = j;
        break;
      }
    if (tar != i) {
      sum = (P - sum) % P;
      for (rint j = 1; j < n; ++j) std::swap(deg[tar][j], deg[i][j]);
    }
    sum = sum * deg[i][i] % P;
    LL inv = qpow(deg[i][i]);
    for (rint j = 1; j < n; ++j) deg[i][j] = deg[i][j] * inv % P;
    for (rint j = i + 1; j < n; ++j) {
      rint tmp = deg[j][i];
      for (rint k = 1; k < n; ++k) deg[j][k] = (deg[j][k] + deg[i][k] * (P - tmp)) % P;
    }
  }
  det[x][y] = sum;
}

LL f[MAXN][MAXN], F[MAXN][MAXN];

inline int main() {
  int x, y;
  cin >> n >> m >> x >> y;
  for (int i = 1; i <= m; ++i) {
    int u, v, w;
    cin >> u >> v >> w;
    e[u][v][w]++;
    e[v][u][w]++;
  }
  for (int i = 0; i <= n; ++i)
    for (int j = 0; j <= n; ++j) matrixTree(i, j);
  for (int i = 0; i <= n; ++i) {
    f[i][0] = 1;
    LL inv = 1;
    for (int j = 0; j < n; ++j) {
      if (i == j) continue;
      for (int k = j; k >= 0; --k) {
        f[i][k + 1] = (f[i][k + 1] + f[i][k]) % P;
        f[i][k] = f[i][k] * (P - j) % P;
      }
      inv = inv * (i - j + P) % P;
    }
    inv = qpow(inv, P - 2);
    for (int j = 0; j < n; ++j) f[i][j] = f[i][j] * inv % P;
  }
  for (int i = 0; i < n; ++i)
    for (int j = 0; j < n; ++j)
      for (int k = 0; k < n; ++k)
        for (int l = 0; l < n; ++l) F[k][l] = (F[k][l] + f[i][k] * f[j][l] % P * det[i][j] % P) % P;
  LL ans = 0;
  for (int i = 0; i <= x; ++i)
    for (int j = 0; j <= y; ++j) {
      ans = (ans + F[i][j]) % P;
    }
  cout << ans;
  return 0;
}

}  // namespace BlueQuantum

int main() {
#ifndef ONLINE_JUDGE
#ifdef LOCAL
  freopen("/tmp/CodeTmp/testdata.in", "r", stdin);
  freopen("/tmp/CodeTmp/testdata.out", "w", stdout);
#else
  freopen("tree.in", "r", stdin);
  freopen("tree.out", "w", stdout);
#endif
#endif

  std::ios::sync_with_stdio(false), cin.tie(NULL), cout.tie(NULL);
  return BlueQuantum::main();
}
